#pragma once

#include "data_structure.h"
#include "map_collect.h"
#include "eventcommand.h"
#include "geos.h"
#include "raw_message.h"

#include <cmath>
#include <map>
#include <vector>

using namespace std;

/*
{
"fences":[
    {
        "fenceType":3001,
        "geom":"POLYGON ((106.56624558615893 29.561743956078406, 106.56639218365163 29.56191136679538, 106.56654264859665 29.561779608302977, 106.5663942324725 29.561610120753798, 106.56639048340256 29.561606070584457, 106.56633126902486 29.561545540331693, 106.56634552995973 29.561473925637028, 106.56611452995973 29.561427925637027, 106.56610325898033 29.56142634163736, 106.56592225898034 29.56141134163736, 106.56590550370142 29.561411361589183, 106.56577650370141 29.561422361589184, 106.5657546118422 29.561426729018766, 106.56563861184219 29.561463729018765, 106.56560573563772 29.561481555694435, 106.56553473563771 29.561539555694434, 106.56553424322858 29.56153996056789, 106.56550524322859 29.561563960567895, 106.56547864208324 29.561598157884294, 106.56542364208323 29.561714157884293, 106.56541526175623 29.561741164621285, 106.56539826175623 29.561847164621284, 106.56539756908461 29.56187365331237, 106.56540953144071 29.561985301969113, 106.56541149628097 29.56200495037188, 106.56542697033518 29.562049212686986, 106.56548697033519 29.562142212686986, 106.56550170784392 29.562160101297533, 106.56557870784391 29.562234101297534, 106.56559252998038 29.562245205029434, 106.56573729105881 29.562341712415055, 106.56580852725317 29.562412948609403, 106.56582753575756 29.562442819116306, 106.5659962680551 29.562335444017855, 106.56597136614877 29.562296312450773, 106.56595771067812 29.562279289321875, 106.56587171067811 29.562193289321876, 106.56585647001961 29.562180794970566, 106.56571087519941 29.562083731757106, 106.56564870447484 29.562023983268542, 106.56560807278653 29.561961004151673, 106.56559785491244 29.561865637326903, 106.56561047663301 29.561786937186866, 106.56564985145502 29.561703892107737, 106.56566151121257 29.561694242653214, 106.56571752290613 29.561648486621856, 106.565804687499 29.56162068412241, 106.56591411949782 29.561611352711658, 106.56607036127997 29.561624300925647, 106.56617125198981 29.561667970038865, 106.56624558615893 29.561743956078406))",
        "hasVideo":false,
        "id":"2892",
        "timeOut":0 //秒
    }
]
}
*/

enum FenceStatus {
  FENCE_INVALID,
  FENCE_FIRSTIN,
  FENCE_IN,
  FENCE_OUT,
  FENCE_WAIT //此电子围栏已结束，等待矢量化数据采集完毕
};
const double mapEpsilon = 1e-6; // 根据需要调整,浮点数直接比较存在风险
//一个电子围栏的配置
typedef struct FenceInfo_t
{
    //3001-全局INS围栏;2001-众包2.0采集围栏;1000-众包1.0采集围栏 
    uint32_t type;
    std::shared_ptr<geos::geom::Geometry> geom_polygon{nullptr};
    std::string id;
    bool hasvedio = false;
    uint32_t tiemout = 20*60 * 1000;//20min 内部计算用ms，外部json传来时秒;超时时间内的采集才认为有效，进行上传；否则删文件不上传事件

    //围栏动态状态 0:初始值； 1：首次进入围栏  2：离开围栏 3：一直在围栏里
    uint8_t status = FenceStatus::FENCE_INVALID;
    double firstInTime = 0.0;//CommonOprTime::getTime()

    uint64_t firstInTime_csmap = 0;//ins的时间
    uint64_t OutTime_csmap = 0;//ins的时间

    string eventid;
    //需要采集的信号/topic
    std::vector<std::string> collectDatas;
}FenceInfo_t;


namespace DcAdr
{
    // class MapCollect : public EventCommand    
    class MapCollect
    {
    private:
        /* data */
    public:
        static MapCollect &getInstance();
        bool IsValid(const double &lon, const double &lat);
        void mapEventhappen(const std::string &topic, const string &data, const double &time);
        void mapEventhappen();

        void SetSpeed(const string &data);

        bool saveConfig(const std::string &confCloud);
        bool deletFenceConfig(const std::string &fenceId);
        bool parseMapConfigJsonData(const std::string &json);

    private:
        bool isConfigLoad = false;
        MapCollect(/* args */);
        ~MapCollect();

        bool parseMapCollect(const Json::Value &value);
        bool GetCsmapTimeFromFile(const string &filename, uint64_t &begtime, uint64_t &endtime);
        bool CsmapCollectFinish(uint64_t firstInTime_csmap, uint64_t OutTime_csmap, std::vector<TrigerFile> &otherSysFile);
        bool OneTypeFenceJudge(const uint8_t &inoutStatus, std::vector<FenceInfo_t>::iterator &it, std::vector<FenceInfo_t> &fences);
        bool InsidePolygonWkt(double &lon,  double &lat, const std::shared_ptr<geos::geom::Geometry> &geom_polygon);

    private:
        double m_spd = 0.0;//zjs_test;
        uint64_t m_csmap_time = 0;//s乘以1000000 随ins递增
        double  CSMAP_4_Collect_fin_time = 0;
        GeometryFactory::Ptr factory;
        // geos::io::WKTReader reader;
        geos::io::WKTReader *readerPoint{nullptr};
        // std::unique_ptr<geos::io::WKTReader> readerPrt{nullptr};
        map<uint32_t, std::vector<FenceInfo_t>> m_eventFence;     //一种类型可能有多个电子围栏；eg：map<1000, std::vector<FenceInfo_t>>

    };
}
